#
# This file is part of the kernelstudio package.
#
# (c) 2014-2025 zlin <admin@kernelstudio.com>
#
# For the full copyright and license information, please view the LICENSE file
# that was distributed with this source code.
import hashlib
import os
import typing as t
from pathlib import Path

from ksai.serializer import JsonSerializable


class Attachment(JsonSerializable):
    uuid: t.Optional[str]
    sign: t.Optional[str]
    filename: t.Optional[str]
    original_name: t.Optional[str]
    mime: t.Optional[str]
    filepath: t.Optional[str]
    size: t.Optional[int]
    suffix: t.Optional[str]
    channel: t.Optional[str]
    category: t.Optional[str]
    content: t.Optional[bytes]
    url: t.Optional[str]

    def __init__(self,
                 uuid: t.Optional[str] = None,
                 sign: t.Optional[str] = None,
                 mime: t.Optional[str] = None,
                 filename: t.Optional[str] = None,
                 original_name: t.Optional[str] = None,
                 filepath: t.Optional[str] = None,
                 size: t.Optional[int] = None,
                 suffix: t.Optional[str] = None,
                 channel: t.Optional[str] = None,
                 category: t.Optional[str] = None,
                 content: t.Optional[bytes] = None,
                 url: t.Optional[str] = None
                 ):
        self.uuid = uuid
        self.sign = sign
        self.mime = mime
        self.filename = filename
        self.original_name = original_name
        self.filepath = filepath
        self.size = size
        self.suffix = suffix
        self.channel = channel
        self.category = category
        self.content = content
        self.url = url

    @staticmethod
    def from_file(filepath: t.Union[str, Path]) -> "Attachment":
        if not os.path.isfile(filepath):
            raise FileNotFoundError(filepath)
        with open(filepath, 'rb') as f:
            content = f.read()
        suffix = os.path.splitext(filepath)[1]
        sign = hashlib.md5(content).hexdigest()
        f = Attachment(
            uuid=sign,
            content=content,
            suffix=suffix,
            filepath=filepath,
            filename=filepath.split(os.path.sep)[-1],
            size=len(content),
            sign=sign,
        )
        return f

    @property
    def content_string(self) -> str:
        return str(self.content, 'utf-8')

    def serialize(self) -> t.Optional[dict]:
        return {
            'uuid': self.uuid,
            'sign': self.sign,
            'mime': self.mime,
            'filename': self.filename,
            'original_name': self.original_name,
            'filepath': self.filepath,
            'size': self.size,
            'category': self.category,
            'channel': self.channel,
            'suffix': self.suffix,
            'url': self.url,
        }
